package com.lyy.system.controller;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lyy.common.utils.*;
import com.lyy.common.utils.excel.ExcelUtils;
import com.lyy.common.utils.jxls.JxlsExport;
import com.lyy.system.pojo.SysTask;
import com.lyy.system.service.SysTaskService;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * 定时任务(SysTask)表控制层
 *
 * @author Yw
 * @since 2021-02-02 19:52:41
 */
@RestController
@RequestMapping("/sysTask")
public class SysTaskController {
    /**
     * 服务对象
     */
    @Resource
    private SysTaskService sysTaskService;

    /**
     * 创建定时任务
     * /sysTask/createSysTask
     * { "taskName":"任务名称",  "taskCron":"定时任务的cron",  "className":"类名",  "methodName":"执行方法名",  "createDate":"创建时间",  "createBy":"创建者",  "updateDate":"更新时间",  "updateBy":"更新者",  "delFlag":"删除状态 0正常 1删除" }
     *
     * @param taskName   任务名称
     * @param taskCron   定时任务的cron
     * @param className  类名
     * @param methodName 执行方法名
     * @param createDate 创建时间
     * @param createBy   创建者
     * @param updateDate 更新时间
     * @param updateBy   更新者
     * @param delFlag    删除状态 0正常 1删除
     * @return
     */
    @PostMapping("/createSysTask")
    public Map<String, Object> createSysTask(SysTask sysTask) {
        AssertUtils.notNull(sysTask.getTaskName(), "任务名称不能为空");
        AssertUtils.notNull(sysTask.getTaskCron(), "定时任务的cron不能为空");
        AssertUtils.notNull(sysTask.getClassName(), "类名不能为空");
        AssertUtils.notNull(sysTask.getMethodName(), "执行方法名不能为空");
        AssertUtils.notNull(sysTask.getCreateDate(), "创建时间不能为空");
        AssertUtils.notNull(sysTask.getCreateBy(), "创建者不能为空");
        AssertUtils.notNull(sysTask.getUpdateDate(), "更新时间不能为空");
        AssertUtils.notNull(sysTask.getUpdateBy(), "更新者不能为空");
        AssertUtils.notNull(sysTask.getDelFlag(), "删除状态 0正常 1删除不能为空");
        sysTaskService.createSysTask(sysTask);
        return ResultUtils.getResult(ResultInfo.SUCCESS);
    }

    /**
     * 根据主键修改定时任务
     * /sysTask/updateSysTask
     * { "id":"任务id",  "taskName":"任务名称",  "taskCron":"定时任务的cron",  "className":"类名",  "methodName":"执行方法名",  "createDate":"创建时间",  "createBy":"创建者",  "updateDate":"更新时间",  "updateBy":"更新者",  "delFlag":"删除状态 0正常 1删除" }
     *
     * @param id         任务id
     * @param taskName   任务名称
     * @param taskCron   定时任务的cron
     * @param className  类名
     * @param methodName 执行方法名
     * @param createDate 创建时间
     * @param createBy   创建者
     * @param updateDate 更新时间
     * @param updateBy   更新者
     * @param delFlag    删除状态 0正常 1删除
     * @return
     */
    @PutMapping("/updateSysTask")
    public Map<String, Object> updateSysTask(SysTask sysTask) {
        AssertUtils.notNull(sysTask.getId(), "任务id不能为空");
        AssertUtils.notNull(sysTask.getTaskName(), "任务名称不能为空");
        AssertUtils.notNull(sysTask.getTaskCron(), "定时任务的cron不能为空");
        AssertUtils.notNull(sysTask.getClassName(), "类名不能为空");
        AssertUtils.notNull(sysTask.getMethodName(), "执行方法名不能为空");
        AssertUtils.notNull(sysTask.getCreateDate(), "创建时间不能为空");
        AssertUtils.notNull(sysTask.getCreateBy(), "创建者不能为空");
        AssertUtils.notNull(sysTask.getUpdateDate(), "更新时间不能为空");
        AssertUtils.notNull(sysTask.getUpdateBy(), "更新者不能为空");
        AssertUtils.notNull(sysTask.getDelFlag(), "删除状态 0正常 1删除不能为空");
        sysTaskService.updateSysTask(sysTask);
        return ResultUtils.getResult(ResultInfo.SUCCESS);
    }

    /**
     * 根据主键获取单个定时任务
     * /sysTask/getSysTask
     * { "id":"任务id" }
     *
     * @param id 任务id
     * @return
     */
    @GetMapping("/getSysTask")
    public Map<String, Object> getSysTask(SysTask sysTask) {
        AssertUtils.notNull(sysTask.getId(), "任务id不能为空");
        SysTask entity = sysTaskService.getSysTask(sysTask);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("sysTask", entity);
        return ResultUtils.getResult(ResultInfo.SUCCESS, "", map);
    }


    /**
     * 根据主键删除定时任务
     * /sysTask/deleteSysTask
     * { "id":"任务id" }
     *
     * @param id 任务id
     * @return
     */
    @DeleteMapping("/deleteSysTask")
    public Map<String, Object> deleteSysTask(SysTask sysTask) {
        AssertUtils.notNull(sysTask.getId(), "任务id不能为空");
        sysTaskService.deleteSysTask(sysTask);
        return ResultUtils.getResult(ResultInfo.SUCCESS);
    }

    /**
     * 查询定时任务列表
     * /sysTask/selectSysTaskList
     * { "id":"任务id",  "taskName":"任务名称",  "taskCron":"定时任务的cron",  "className":"类名",  "methodName":"执行方法名",  "createDate":"创建时间",  "createBy":"创建者",  "updateDate":"更新时间",  "updateBy":"更新者",  "delFlag":"删除状态 0正常 1删除" }
     *
     * @param id         任务id
     * @param taskName   任务名称
     * @param taskCron   定时任务的cron
     * @param className  类名
     * @param methodName 执行方法名
     * @param createDate 创建时间
     * @param createBy   创建者
     * @param updateDate 更新时间
     * @param updateBy   更新者
     * @param delFlag    删除状态 0正常 1删除
     * @return
     */
    @GetMapping("/selectSysTaskList")
    public Map<String, Object> selectSysTaskList(SysTask sysTask) {
        List<SysTask> sysTasks = sysTaskService.selectSysTaskList(sysTask);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("sysTasks", sysTasks);
        return ResultUtils.getResult(ResultInfo.SUCCESS, "", map);
    }

    /**
     * 查询定时任务列表
     * /sysTask/selectSysTaskCount
     * { "id":"任务id", "taskName":"任务名称", "taskCron":"定时任务的cron", "className":"类名", "methodName":"执行方法名", "createDate":"创建时间", "createBy":"创建者", "updateDate":"更新时间", "updateBy":"更新者", "delFlag":"删除状态 0正常 1删除"}
     *
     * @param id         任务id
     * @param taskName   任务名称
     * @param taskCron   定时任务的cron
     * @param className  类名
     * @param methodName 执行方法名
     * @param createDate 创建时间
     * @param createBy   创建者
     * @param updateDate 更新时间
     * @param updateBy   更新者
     * @param delFlag    删除状态 0正常 1删除
     * @return
     */
    @GetMapping("/selectSysTaskCount")
    public Map<String, Object> selectSysTaskCount(SysTask sysTask) {
        int count = sysTaskService.selectSysTaskCount(sysTask);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("count", count);
        return ResultUtils.getResult(ResultInfo.SUCCESS, "", map);
    }


    /**
     * 查询定时任务列表分页
     * /sysTask/selectSysTaskPage
     * { "id":"任务id",  "taskName":"任务名称",  "taskCron":"定时任务的cron",  "className":"类名",  "methodName":"执行方法名",  "createDate":"创建时间",  "createBy":"创建者",  "updateDate":"更新时间",  "updateBy":"更新者",  "delFlag":"删除状态 0正常 1删除" ,"pageNum":"页码","pageSize":"条数"}
     *
     * @param pageNum    页码
     * @param pageSize   页数
     * @param id         任务id
     * @param taskName   任务名称
     * @param taskCron   定时任务的cron
     * @param className  类名
     * @param methodName 执行方法名
     * @param createDate 创建时间
     * @param createBy   创建者
     * @param updateDate 更新时间
     * @param updateBy   更新者
     * @param delFlag    删除状态 0正常 1删除
     * @return
     */
    @GetMapping("/selectSysTaskPage")
    public Map<String, Object> selectSysTaskPage(SysTask sysTask, Integer pageNum, Integer pageSize) {
        AssertUtils.notNull(pageNum, "页码不能为空!");
        AssertUtils.notNull(pageSize, "条数不能为空!");
        PageHelper.startPage(pageNum, pageSize);
        List<SysTask> sysTasks = sysTaskService.selectSysTaskList(sysTask);
        PageInfo<SysTask> pageInfo = new PageInfo<>(sysTasks);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("pageInfo", pageInfo);
        return ResultUtils.getResult(ResultInfo.SUCCESS, "", map);
    }


    /**
     * 导出定时任务
     * /sysTask/exportSysTaskExcel
     * { "id":"任务id",  "taskName":"任务名称",  "taskCron":"定时任务的cron",  "className":"类名",  "methodName":"执行方法名",  "createDate":"创建时间",  "createBy":"创建者",  "updateDate":"更新时间",  "updateBy":"更新者",  "delFlag":"删除状态 0正常 1删除" }
     *
     * @param id         任务id
     * @param taskName   任务名称
     * @param taskCron   定时任务的cron
     * @param className  类名
     * @param methodName 执行方法名
     * @param createDate 创建时间
     * @param createBy   创建者
     * @param updateDate 更新时间
     * @param updateBy   更新者
     * @param delFlag    删除状态 0正常 1删除
     * @return
     */
    @GetMapping("/exportSysTaskExcel")
    public void exportSysTaskExcel(HttpServletRequest request, HttpServletResponse response, SysTask sysTask) {
        List<SysTask> sysTasks = sysTaskService.selectSysTaskList(sysTask);
        if (CommonUtils.isNotEmpty(sysTasks)) {
            List<String> titles = new ArrayList<>();
            titles.add(" 序号 ");
            titles.add(" 任务名称 ");
            titles.add(" 定时任务的cron ");
            titles.add(" 类名 ");
            titles.add(" 执行方法名 ");
            titles.add(" 创建时间 ");
            titles.add(" 创建者 ");
            titles.add(" 更新时间 ");
            titles.add(" 更新者 ");
            titles.add(" 删除状态 0正常 1删除 ");
            List<List<String>> values = new ArrayList<>();
            int k = 0;
            for (SysTask entity : sysTasks) {
                List<String> value = new ArrayList<>();
                value.add((++k) + "");
                value.add(entity.getTaskName());
                value.add(entity.getTaskCron());
                value.add(entity.getClassName());
                value.add(entity.getMethodName());
                value.add(DateUtils.formatDate(entity.getCreateDate()));
                value.add(entity.getCreateBy());
                value.add(DateUtils.formatDate(entity.getUpdateDate()));
                value.add(entity.getUpdateBy());
                value.add(entity.getDelFlag());
                values.add(value);
            }
            String address = Constants.address + "/wisdom/template/customTemplate.xls";
            String excelName = "定时任务.xls";
            Map<String, Object> beans = new HashMap<>();
            beans.put("titles", titles);
            beans.put("values", values);
            beans.put("date", DateUtils.formatDateTime(new Date()));
            JxlsExport.export(request, response, beans, excelName, address);
        }
    }

    /**
     * 根据主键逻辑删除定时任务
     * /sysTask/deleteSysTaskLogic
     * { "id":"任务id" }
     *
     * @param id 任务id
     * @return
     */
    @PutMapping("/deleteSysTaskLogic")
    public Map<String, Object> deleteSysTaskLogic(SysTask sysTask) {
        sysTask.setDelFlag("1");
        sysTaskService.updateSysTask(sysTask);
        return ResultUtils.getResult(ResultInfo.SUCCESS);
    }

    /**
     * /sysTask/importSysTaskExcel  从excel表导入定时任务
     * 导入excel文件
     * {"file":"excel文件"}
     *
     * @param file excel文件
     */
    @PostMapping("/importSysTaskExcel")
    public Map<String, Object> importSysTaskExcel(MultipartFile file) {
        if (file.isEmpty()) {
            return ResultUtils.getResult(ResultInfo.UPLOAD_NOT_EXISTS);
        }
        // 文件名称
        String fileName = file.getOriginalFilename();
        if (StringUtils.isBlank(fileName)) {
            return ResultUtils.getResult(ResultInfo.UPLOAD_NOT_EXISTS);
        }
        try {
            InputStream inputStream = file.getInputStream();
            //创建工作簿
            Workbook wb = null;
            //判断表格格式
            if (fileName.toLowerCase().endsWith("xls")) {
                wb = new HSSFWorkbook(inputStream);
            } else if (fileName.toLowerCase().endsWith("xlsx")) {
                wb = new XSSFWorkbook(inputStream);
            } else {
                return ResultUtils.getResult(ResultInfo.UPLOAD_TYPE_ERROR);
            }
            List<SysTask> sysTasks = new ArrayList<>();
            List<Map<String, String>> resultMap = new ArrayList<>();
            Map<String, String> result = null;
            SysTask sysTask = null;
            // 获取工作表的第一个Sheet
            Sheet hssfSheet = wb.getSheetAt(0);
            if (hssfSheet != null) {
                int index = -1;
                for (int rowNum = 0; rowNum <= hssfSheet.getLastRowNum(); rowNum++) {
                    Row hssfRow = hssfSheet.getRow(rowNum);
                    if (hssfRow != null) {
                        if (ExcelUtils.getValue(hssfRow.getCell(0)).contains("任务名称") &&
                                ExcelUtils.getValue(hssfRow.getCell(1)).contains("定时任务的cron") &&
                                ExcelUtils.getValue(hssfRow.getCell(2)).contains("类名") &&
                                ExcelUtils.getValue(hssfRow.getCell(3)).contains("执行方法名") &&
                                ExcelUtils.getValue(hssfRow.getCell(4)).contains("创建时间") &&
                                ExcelUtils.getValue(hssfRow.getCell(5)).contains("创建者") &&
                                ExcelUtils.getValue(hssfRow.getCell(6)).contains("更新时间") &&
                                ExcelUtils.getValue(hssfRow.getCell(7)).contains("更新者") &&
                                ExcelUtils.getValue(hssfRow.getCell(8)).contains("删除状态 0正常 1删除")) {
                            index = ++rowNum;
                            break;
                        }
                    }
                }

                if (index == -1) {
                    result = new HashMap<>();
                    result.put("reason", "excel模板不正确");
                    result.put("status", "1");
                    resultMap.add(result);
                    Map<String, Object> map = new HashMap<>();
                    map.put("resultMap", resultMap);
                    return ResultUtils.getResult(ResultInfo.SUCCESS, "", map);
                }

                // 循环行Row
                for (int rowNum = index; rowNum <= hssfSheet.getLastRowNum(); rowNum++) {
                    Row hssfRow = hssfSheet.getRow(rowNum);
                    if (hssfRow != null) {
                        if (StringUtils.isBlank(ExcelUtils.getValue(hssfRow.getCell(0))) &&
                                StringUtils.isBlank(ExcelUtils.getValue(hssfRow.getCell(1))) &&
                                StringUtils.isBlank(ExcelUtils.getValue(hssfRow.getCell(2))) &&
                                StringUtils.isBlank(ExcelUtils.getValue(hssfRow.getCell(3))) &&
                                StringUtils.isBlank(ExcelUtils.getValue(hssfRow.getCell(4))) &&
                                StringUtils.isBlank(ExcelUtils.getValue(hssfRow.getCell(5))) &&
                                StringUtils.isBlank(ExcelUtils.getValue(hssfRow.getCell(6))) &&
                                StringUtils.isBlank(ExcelUtils.getValue(hssfRow.getCell(7))) &&
                                StringUtils.isBlank(ExcelUtils.getValue(hssfRow.getCell(8)))) {
                            continue;
                        }
                        sysTask = new SysTask();
                        String taskName = ExcelUtils.getValue(hssfRow.getCell(0));//任务名称
                        if (StringUtils.isBlank(taskName)) {
                            result = new HashMap<>();
                            result.put("reason", "任务名称不能为空！");
                            result.put("status", "1");
                            resultMap.add(result);
                            continue;
                        }
                        sysTask.setTaskName(taskName);
                        String taskCron = ExcelUtils.getValue(hssfRow.getCell(1));//定时任务的cron
                        if (StringUtils.isBlank(taskCron)) {
                            result = new HashMap<>();
                            result.put("reason", "定时任务的cron不能为空！");
                            result.put("status", "1");
                            resultMap.add(result);
                            continue;
                        }
                        sysTask.setTaskCron(taskCron);
                        String className = ExcelUtils.getValue(hssfRow.getCell(2));//类名
                        if (StringUtils.isBlank(className)) {
                            result = new HashMap<>();
                            result.put("reason", "类名不能为空！");
                            result.put("status", "1");
                            resultMap.add(result);
                            continue;
                        }
                        sysTask.setClassName(className);
                        String methodName = ExcelUtils.getValue(hssfRow.getCell(3));//执行方法名
                        if (StringUtils.isBlank(methodName)) {
                            result = new HashMap<>();
                            result.put("reason", "执行方法名不能为空！");
                            result.put("status", "1");
                            resultMap.add(result);
                            continue;
                        }
                        sysTask.setMethodName(methodName);
                        String createDate = ExcelUtils.getValue(hssfRow.getCell(4));//创建时间
                        if (StringUtils.isBlank(createDate)) {
                            result = new HashMap<>();
                            result.put("reason", "创建时间不能为空！");
                            result.put("status", "1");
                            resultMap.add(result);
                            continue;
                        }
                        sysTask.setCreateDate(DateUtils.formatDate(createDate));
                        String createBy = ExcelUtils.getValue(hssfRow.getCell(5));//创建者
                        if (StringUtils.isBlank(createBy)) {
                            result = new HashMap<>();
                            result.put("reason", "创建者不能为空！");
                            result.put("status", "1");
                            resultMap.add(result);
                            continue;
                        }
                        sysTask.setCreateBy(createBy);
                        String updateDate = ExcelUtils.getValue(hssfRow.getCell(6));//更新时间
                        if (StringUtils.isBlank(updateDate)) {
                            result = new HashMap<>();
                            result.put("reason", "更新时间不能为空！");
                            result.put("status", "1");
                            resultMap.add(result);
                            continue;
                        }
                        sysTask.setUpdateDate(DateUtils.formatDate(updateDate));
                        String updateBy = ExcelUtils.getValue(hssfRow.getCell(7));//更新者
                        if (StringUtils.isBlank(updateBy)) {
                            result = new HashMap<>();
                            result.put("reason", "更新者不能为空！");
                            result.put("status", "1");
                            resultMap.add(result);
                            continue;
                        }
                        sysTask.setUpdateBy(updateBy);
                        String delFlag = ExcelUtils.getValue(hssfRow.getCell(8));//删除状态 0正常 1删除
                        if (StringUtils.isBlank(delFlag)) {
                            result = new HashMap<>();
                            result.put("reason", "删除状态 0正常 1删除不能为空！");
                            result.put("status", "1");
                            resultMap.add(result);
                            continue;
                        }
                        sysTask.setDelFlag(delFlag);
                        sysTasks.add(sysTask);
                    }
                }
                if (CommonUtils.isNotEmpty(sysTasks)) {
                    resultMap.addAll(sysTaskService.importSysTaskExcel(sysTasks));
                }
            }
            inputStream.close();
            Map<String, Object> map = new HashMap<>();
            map.put("resultMap", resultMap);
            return ResultUtils.getResult(ResultInfo.SUCCESS, "", map);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtils.getResult(ResultInfo.ERROR);
        }
        return ResultUtils.getResult(ResultInfo.FAILED);
    }
}